package com.bestcem.xm.user.service.impl;

import cn.hutool.core.lang.ObjectId;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.enums.ReqErrorCodeEnum;
import com.bestcem.xm.common.core.enums.ResourceErrorCodeEnum;
import com.bestcem.xm.common.core.exception.BusinessException;
import com.bestcem.xm.component.security.dto.TokenDTO;
import com.bestcem.xm.user.constant.UserGroupConstant;
import com.bestcem.xm.user.controller.vo.group.UserGroupLevelOldVO;
import com.bestcem.xm.user.dao.UserGroupDao;
import com.bestcem.xm.user.dao.UserGroupLevelDao;
import com.bestcem.xm.user.entity.pojo.UserGroupDO;
import com.bestcem.xm.user.entity.pojo.UserGroupLevelDO;
import com.bestcem.xm.user.enums.UserEnum;
import com.bestcem.xm.user.mq.send.biz.UserMessageSendService;
import com.bestcem.xm.user.service.OrganizationService;
import com.bestcem.xm.user.service.UserGroupLevelService;
import com.bestcem.xm.user.service.UserGroupService;
import com.bestcem.xm.user.service.UserUserGroupService;
import com.bestcem.xm.user.service.dto.group.*;
import com.bestcem.xm.user.service.dto.user.OrganizationDTO;
import com.bestcem.xm.user.util.business.GroupSequenceUtil;
import com.bestcem.xm.user.util.convert.UserGroupLevelConvert;
import com.bestcem.xm.user.util.converter.UserGroupLevelConverter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户层级service实现
 *
 * @author wangyunyun <yunyun.wang@idiaoyan.com>
 * @version v1.0
 * @date 2021/12/29 17:39
 */
@Slf4j
@Service
public class UserGroupLevelServiceImpl implements UserGroupLevelService {

    @Resource
    private UserGroupLevelConvert userGroupLevelConvert;

    @Resource
    private GroupSequenceUtil groupSequenceUtil;

    @Resource
    private UserGroupLevelDao userGroupLevelDao;

    @Resource
    private UserGroupService userGroupService;

    @Resource
    private UserUserGroupService userUserGroupService;

    //@Resource
    //private UserGroupMessageSender userGroupMessageSender;

    @Resource
    private UserMessageSendService userMessageSendService;

    @Resource
    private OrganizationService organizationService;

    @Resource
    private UserGroupDao userGroupDao;

    @Override
    public ServiceResult<String> insert(UserGroupLevelDTO dto) {
        // 校验参数
        if (Objects.isNull(dto)) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_FORMAT, "参数为空或格式不正确");
        }
        // 查询并设置返回值
        return ServiceResult.success(userGroupLevelDao.insert(userGroupLevelConvert.dtoToDo(dto)));
    }

    @Override
    public ServiceResult<Boolean> insertBatch(List<UserGroupLevelDTO> dtos) {
        // 校验参数
        if (CollectionUtils.isEmpty(dtos)) {
            return ServiceResult.fail("参数为空");
        }
        // 查询并设置返回值
        userGroupLevelDao.insertBatch(userGroupLevelConvert.dtosToDos(dtos));
        return ServiceResult.success(true);
    }

    @Override
    public ServiceResult<Integer> deleteByIds(List<String> ids) {
        // 校验参数
        if (CollectionUtils.isEmpty(ids)) {
            return ServiceResult.fail("参数为空");
        }
        // 删除
        return ServiceResult.success(userGroupLevelDao.deleteByIds(ids));
    }

    @Override
    public ServiceResult<List<UserGroupLevelDTO>> listByOrgId(String orgId) {
        // 校验参数
        if (!ObjectId.isValid(orgId)) {
            return ServiceResult.fail("参数为空或格式不正确");
        }
        // 设置参数
        UserGroupLevelDO condition = new UserGroupLevelDO();
        condition.setOrgId(orgId);
        // 查询并设置返回值
        return ServiceResult.success(userGroupLevelConvert.dosToDtos(userGroupLevelDao.listByCondition(condition)));
    }

    /**
     * 根据层级id查询层级信息
     *
     * @param id 层级id
     * @return 层级信息
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2021/12/30 15:53
     */
    @Override
    public ServiceResult<UserGroupLevelDTO> getById(String id) {
        // 校验参数
        if (!ObjectId.isValid(id)) {
            return ServiceResult.fail("参数为空或格式不正确");
        }
        // 查询并设置返回值
        UserGroupLevelDO userGroupLevelDO = userGroupLevelDao.getById(id);
        return ServiceResult.success(userGroupLevelConvert.doToDto(userGroupLevelDO));
    }

    /**
     * 保存当前公司下用户组层级列表
     *
     * @param levelDTO 前端传入的组织结构列表
     * @return com.bestcem.xm.util.XmResultJson
     * @author jishuo.yan <jishuo.yan@idiaoyan.com>
     * @date 2022/01/04 15:08
     */
    @Override
    public ServiceResult<Boolean> saveGroupLevel(SaveGroupLevelDTO levelDTO) {

        // 通过前端传入组织id 获取组织结构
        UserGroupLevelDO levelDO = new UserGroupLevelDO();
        levelDO.setOrgId(levelDTO.getOrgId());
        // 当前组织结构和组织id
        List<UserGroupLevelDO> userGroupLevelList = userGroupLevelDao.listByCondition(levelDO);
        //版本号校验
        if (!CollectionUtils.isEmpty(userGroupLevelList) && !Objects.equals(levelDTO.getVersion(), userGroupLevelList.get(0).getVersionId())) {
            return ServiceResult.fail("version版本不一致，不允许更新");
        }
//        前端传来的组织结构和组织id
//        比较版本号信息，校验大小 两个集合比较大小，如果一样，则允许更新，不一样则不允许更新
//        需要新增的层级，version值为0;(从0开始定义，建一个全局的类default:0)
        List<String> groupLevelIds = userGroupLevelList.stream().map(UserGroupLevelDO::getGroupLevelId).collect(Collectors.toList());
        List<GroupLevelDTO> insertLevel = levelDTO.getGroupLevels().stream().filter(s -> s.getGroupLevelId() == null).collect(Collectors.toList());
        List<UserGroupLevelDTO> insertDtos = insertLevel.stream().map(i -> {
            UserGroupLevelDTO userGroupLevelDTO = new UserGroupLevelDTO();
            userGroupLevelDTO.setCreatorId(levelDTO.getUserId());
            userGroupLevelDTO.setOperatorId(levelDTO.getUserId());
            userGroupLevelDTO.setLevelChildrenId("");
            userGroupLevelDTO.setVersionId(i.getVersionId());
            userGroupLevelDTO.setLevelStatus(0);
            userGroupLevelDTO.setLevelDisplay("");

            userGroupLevelDTO.setGroupLevelId(i.getGroupLevelId());
            userGroupLevelDTO.setGroupLevelName(i.getGroupLevelName());
            userGroupLevelDTO.setOrgId(levelDTO.getOrgId());
            userGroupLevelDTO.setLevelNum(i.getLevelNum());
            return userGroupLevelDTO;
        }).collect(Collectors.toList());
        insertBatch(insertDtos);

        //需要更新的层级, version=version+1;(原子操作，控制并发，最好是在数据库层面操作)
        List<String> levelIds = levelDTO.getGroupLevels().stream().map(GroupLevelDTO::getGroupLevelId).collect(Collectors.toList());
        List<String> updateIds = levelIds.stream().filter(levelIds::contains).collect(Collectors.toList());
        List<GroupLevelDTO> groupLevelDtos = levelDTO.getGroupLevels().stream().filter(s -> updateIds.contains(s.getGroupLevelId())).collect(Collectors.toList());
        //DTO转DO并更新
        for (GroupLevelDTO updateDTO : groupLevelDtos) {
            //通过DTO的levelID获取对应的DO
            UserGroupLevelDO updateDO = userGroupLevelDao.getById(updateDTO.getGroupLevelId());
            //更新DO的属性
            updateDO.setGroupLevelId(updateDTO.getGroupLevelId());
            updateDO.setGroupLevelName(updateDTO.getGroupLevelName());
            updateDO.setLevelNum(updateDTO.getLevelNum());
            updateDO.setVersionId(updateDTO.getVersionId());
            //更新数据库中的DO
            userGroupLevelDao.updateById(updateDO.getGroupLevelId(), updateDO);
        }

        // 需要删除的层级
        List<String> ids = levelIds.stream().filter(s -> !groupLevelIds.contains(s)).collect(Collectors.toList());
        userGroupLevelDao.deleteByIds(ids);
        return ServiceResult.success(Boolean.TRUE);
    }

    /**
     * 批量设置层级显示字段
     *
     * @param displayDTOList 显示字段列表
     * @param currentToken   当前token
     * @return com.bestcem.xm.util.XmResultJson<java.lang.Object>
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/2/10 23:18
     */
    @Override
    public ServiceResult<Object> setLevelDisplay(List<DisplayDTO> displayDTOList, TokenDTO currentToken) {
        ArrayList<DisplayDTO> updateList = new ArrayList<>();

        //查询层级列表【包含显示字段】
        ServiceResult<List<UserGroupLevelDTO>> displayLevels = getLevelsAndDisplay(currentToken, Boolean.FALSE);
        List<String> displayLevelIds = displayLevels.getData().stream().map(t -> t.getGroupLevelId().toLowerCase()).collect(Collectors.toList());

        for (DisplayDTO dto : displayDTOList) {
            if (displayLevelIds.contains(dto.getLevelId().toLowerCase())) {
                updateList.add(dto);
            }
        }

        for (DisplayDTO dto : updateList) {
            UserGroupLevelDO userGroupLevelDO = new UserGroupLevelDO();

            DisplayJsonDTO displayJsonDTO = new DisplayJsonDTO();
            displayJsonDTO.setAdmin(dto.getAdmin());
            displayJsonDTO.setCode(dto.getCode());
            displayJsonDTO.setTitle(dto.getTitle());

            userGroupLevelDO.setLevelDisplay(JSON.toJSONString(displayJsonDTO));
            userGroupLevelDao.updateById(dto.getLevelId(), userGroupLevelDO);
        }
        return ServiceResult.success();

    }

    /**
     * 查询层级列表【包含显示字段】
     *
     * @param currentToken 当前token
     * @return com.bestcem.xm.util.ServiceResult<java.lang.Object>
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/2/11 14:35
     */
    @Override
    public ServiceResult<List<UserGroupLevelDTO>> getLevelsAndDisplay(TokenDTO currentToken, Boolean all) {
        String orgId = currentToken.getOrgId();

        // 查询所有层级并按levelNum升序排序
        List<UserGroupLevelDO> levels = userGroupLevelDao.getGroupLevelsByOrgId(orgId);

        // 是否是管理员及是否展示所有
        if (currentToken.isAdmin() || all) {
            return ServiceResult.success(userGroupLevelConvert.dosToDtos(levels));
        }

        String userId = currentToken.getUserId();
        // 找出关联组织
        ServiceResult<List<UserGroupDTO>> groupIdsByUserId = userGroupService.getGroupsByUserIdLeftJoinGroup(userId);
        if (CollectionUtils.isEmpty(groupIdsByUserId.getData())) {
            return ServiceResult.success(new ArrayList<>());
        }

        // 过滤出用户关联的结果列表里面的层级id信息，并找出层级数最小的那一个
        Set<String> userGroupLevelIds = groupIdsByUserId.getData().stream().map(UserGroupDTO::getGroupLevelId).collect(Collectors.toSet());
        Integer minLevelNum = levels.stream().filter(l -> userGroupLevelIds.contains(l.getGroupLevelId())).map(UserGroupLevelDO::getLevelNum).min(Integer::compareTo).orElse(null);
        if (Objects.isNull(minLevelNum)) {
            return ServiceResult.success(new ArrayList<>());
        }
        // 得到当前层级和所有的子层级
        List<UserGroupLevelDO> groupLevelDOList = levels.stream().filter(l -> l.getLevelNum() >= minLevelNum).collect(Collectors.toList());
        return ServiceResult.success(userGroupLevelConvert.dosToDtos(groupLevelDOList));
    }

    /**
     * 根据groupId查询它所在层级的levelNum
     *
     * @param groupId 组织id
     * @return com.bestcem.xm.util.ServiceResult<com.bestcem.xm.user.group.service.dto.group.UserGroupLevelDTO>
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/2/16 11:19
     */
    @Override
    public ServiceResult<Integer> getLevelNumByIdJoinLevel(String groupId) {
        return ServiceResult.success(userGroupLevelDao.getLevelNumByIdJoinLevel(groupId));
    }

    /**
     * 根据orgId和层级名称查询层级信息
     *
     * @param orgId          租户id
     * @param groupLevelName 层级名称
     * @return com.bestcem.xm.util.ServiceResult<com.bestcem.xm.user.group.service.dto.group.UserGroupLevelDTO>
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/02/23 13:46
     */
    @Override
    public ServiceResult<UserGroupLevelDTO> getGroupByOrgIdAndName(String orgId, String groupLevelName) {
        UserGroupLevelDO userGroupLevelDO = userGroupLevelDao.getGroupByOrgIdAndName(orgId, groupLevelName);
        return ServiceResult.success(userGroupLevelConvert.doToDto(userGroupLevelDO));
    }

    @Override
    public ServiceResult<Integer> updateById(UserGroupLevelDTO updateLevel) {
        if (updateLevel == null) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_LOST, ReqErrorCodeEnum.PARAM_LOST.getMsg());
        }
        return ServiceResult.success(userGroupLevelDao.updateById(updateLevel.getGroupLevelId(), userGroupLevelConvert.dtoToDo(updateLevel)));
    }

    /**
     * 批量保存用户组层级的显示设置
     *
     * @param displayDTOList 前端传入的显示结构列表
     * @return com.bestcem.xm.util.XmResultJson
     * @author jishuo.yan <jishuo.yan@idiaoyan.com>
     * @date 2022/01/04 15:08
     */
    @Override
    public ServiceResult<Integer> saveGroupLevelDisplay(List<SaveLevelDisplayDTO> displayDTOList) {
        for (SaveLevelDisplayDTO dis : displayDTOList) {
            UserGroupLevelDO levelDO = new UserGroupLevelDO();
            levelDO.setGroupLevelId(dis.getGroupLevelId());
            levelDO.setLevelDisplay(dis.getDisplay().toString());
            userGroupLevelDao.updateById(levelDO.getGroupLevelId(), levelDO);
        }
        return ServiceResult.success(displayDTOList.size());
    }

    /**
     * 查询当前公司下用户组层级列表
     *
     * @param orgId 组织ID
     * @return com.bestcem.xm.util.XmResultJson
     * @author jishuo.yan <jishuo.yan@idiaoyan.com>
     * @date 2022/01/04 15:08
     */
    @Override
    public ServiceResult<List<UserGroupLevelDO>> getGroupLevelDisplay(String orgId) {
        UserGroupLevelDO condition = new UserGroupLevelDO();
        condition.setOrgId(orgId);
        return ServiceResult.success(userGroupLevelDao.listByCondition(condition));
    }


    /**
     * 新增，编辑，删除层级
     *
     * @param groupLevel 层级数据
     * @param orgId      组织id
     * @param userId     用户id
     * @return com.bestcem.xm.util.ServiceResult<java.lang.Boolean>
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/04/02 17:13
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public ServiceResult<Boolean> updateGroupLevel(UpdateGroupLevelDTO groupLevel, String orgId, String userId) {

        ServiceResult<List<String>> groupIdsResult = userUserGroupService.getGroupIdsByUserId(userId);
        List<String> groupIds = groupIdsResult.getData();
        ServiceResult<UserGroupDTO> rootGroupResult = userGroupService.getRootGroupByOrgId(orgId);
        UserGroupDTO rootGroup = rootGroupResult.getData();
        // 非系统管理员/高级管理员 判断当前用户是否在第一层级
        if (!groupLevel.getIsAdmin() && (CollectionUtils.isNotEmpty(groupIds) && !groupIds.contains(rootGroup.getGroupId()))) {
            return ServiceResult.fail("为保障数据安全，非第一层级账号不可以管理层级");
        }

        // 当前组织结构
        // 层级按照levelNum升序排序处理
        List<UserGroupLevelDO> currentGroupLevelList = userGroupLevelDao.getGroupLevelsByOrgId(orgId);
        // 版本校验
        if (!currentGroupLevelList.get(0).getVersionId().equals(groupLevel.getLevelData().get(0).getVersionId())) {
            return ServiceResult.fail("version版本不一致，不允许更新");
        }

        // 前端传来的层级数据
        List<GroupLevelDTO> newData = groupLevel.getLevelData();
        Set<String> levelNameSet = new HashSet<>();
        // 给前端传来的层级赋值层级数
        for (int i = 0; i < newData.size(); i++) {
            newData.get(i).setLevelNum(i);
            if (levelNameSet.contains(newData.get(i).getGroupLevelName())) {
                return ServiceResult.fail(String.format("层级名称 %s 重复", newData.get(i).getGroupLevelName()));
            }
            levelNameSet.add(newData.get(i).getGroupLevelName());
        }

        // 获取前端传来的层级id列表
        List<String> newIds = newData.stream().map(GroupLevelDTO::getGroupLevelId).collect(Collectors.toList());

        // 需要删除的层级,按level_num升序排序
        List<String> deleteLevelIds = currentGroupLevelList.stream()
                .map(UserGroupLevelDO::getGroupLevelId)
                .filter(s -> !newIds.contains(s)).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(deleteLevelIds)) {
            // 删除层级
            userGroupLevelDao.deleteByIds(deleteLevelIds);
            // 被删层级下的层级
            for (String levelId : deleteLevelIds) {
                // 处理层级删除后的组织数据
                userGroupService.handleDeleteLevelGroup(orgId, levelId);
                // 发送层级删除的消息
                userMessageSendService.publishGroupLevelDelete(orgId, levelId);
            }
        }

        // 新的层级数与id的对应关系
        Map<Integer, String> levelNumToIdMap = new HashMap<>();
        for (GroupLevelDTO groupLevelDTO : newData) {
            levelNumToIdMap.put(groupLevelDTO.getLevelNum(), groupLevelDTO.getGroupLevelId());
        }

        // 处理新增和修改的层级
        for (GroupLevelDTO levelDTO : newData) {
            if (StringUtils.isBlank(levelDTO.getGroupLevelId())) {
                UserGroupLevelDO levelDO = new UserGroupLevelDO();
                levelDO.setOrgId(orgId);
                levelDO.setGroupLevelName(levelDTO.getGroupLevelName());
                levelDO.setLevelNum(levelDTO.getLevelNum());
                levelDO.setVersionId(UserGroupConstant.INITIAL_VERSION);
                // python的model类型默认的{}
                levelDO.setLevelDisplay("{}");
                levelDO.setOperatorId(userId);
                levelDO.setCreatorId(userId);
                String groupLevelId = userGroupLevelDao.insert(levelDO);
                // 由于在dao层进行了数据转换，levelDO没有levelId 需要重新赋值
                levelDTO.setGroupLevelId(groupLevelId);
                levelDTO.setVersionId(UserGroupConstant.INITIAL_VERSION);
                // 递归获取下一个层级id不为空的数据 视为下一层级
                String nextLevelId = getNextLevel(levelNumToIdMap, levelDTO.getLevelNum());
                levelNumToIdMap.put(levelDTO.getLevelNum(), groupLevelId);
                userGroupService.saveHiddenGroupForLevel(orgId, levelNumToIdMap.get(levelDTO.getLevelNum() - 1), nextLevelId, groupLevelId);
            }
        }

        // 所有的层级
        List<GroupLevelDTO> data = newData.stream()
                .sorted(Comparator.comparing(GroupLevelDTO::getLevelNum))
                .collect(Collectors.toList());
        List<UserGroupLevelDO> updateData = userGroupLevelConvert.levelDtosToDos(data);
        // 因为新增的层级无法确定level_child_id 需要将层级合并并根据level_num从小到大排序，重新得到level_child_id

        for (int i = 0; i < updateData.size(); i++) {
            UserGroupLevelDO levelDO = updateData.get(i);
            if (i != (updateData.size() - 1)) {
                // 末级层级不更新childLevelId
                UserGroupLevelDO nextLevel = updateData.get(i + 1);
                levelDO.setLevelChildrenId(nextLevel.getGroupLevelId());
            } else {
                // 末级层级childLevelId置为null
                levelDO.setLevelChildrenId(null);
            }
            levelDO.setOperatorId(userId);
            userGroupLevelDao.updateLevel(levelDO);
        }
        // 更新组织树的版本号
        groupSequenceUtil.incrementVersion(orgId);
        // 发送组织变化消息
        ServiceResult<OrganizationDTO> orgResult = organizationService.selectByPrimaryKey(orgId);
        userMessageSendService.publishGroupsChange(orgId, orgResult.getData().getRootGroupId());
        return ServiceResult.success(Boolean.TRUE);
    }

    private String getNextLevel(Map<Integer, String> levelNumToIdMap, Integer levelNum) {
        if (Objects.nonNull(levelNumToIdMap.get(levelNum))) {
            return levelNumToIdMap.get(levelNum);
        }
        return getNextLevel(levelNumToIdMap, levelNum + 1);
    }


    @Override
    public ServiceResult<Integer> updateLevel(UserGroupLevelDTO groupLevelDTO) {
        return ServiceResult.success(userGroupLevelDao.updateLevel(userGroupLevelConvert.dtoToDo(groupLevelDTO)));
    }

    @Override
    public ServiceResult<String> getStoreLevelId(String orgId) {
        if (!ObjectId.isValid(orgId)) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_FORMAT, "orgId格式不正确");
        }

        List<UserGroupLevelDO> groupLevels = userGroupLevelDao.getGroupLevelsByOrgId(orgId);
        if (CollectionUtils.isEmpty(groupLevels)) {
            return ServiceResult.fail(ResourceErrorCodeEnum.NOT_FOUND, "未找到门店的层级信息");
        }
        return ServiceResult.success(groupLevels.get(groupLevels.size() - 1).getGroupLevelId());
    }


    @Override
    public ServiceResult<List<UserGroupLevelDTO>> getGroupLevelUpper(String groupId, String orgCode, String userId) {
        String lastLevelId = null;
        List<UserGroupLevelDTO> groupLevelDTOList = new ArrayList<>();
        UserGroupDTO userGroupDTO;
        if (StringUtils.isBlank(groupId)) {
            // groupId为空则查询出根组织
            ServiceResult<OrganizationDTO> orgResult = organizationService.selectByOrgCode(orgCode);
            OrganizationDTO organizationDTO = orgResult.getData();
            if (Objects.isNull(organizationDTO)) {
                return ServiceResult.success(new ArrayList<>());
            }
            if (StringUtils.isBlank(organizationDTO.getRootGroupId())) {
                return ServiceResult.success(new ArrayList<>());
            }
            assert organizationDTO != null;
            ServiceResult<UserGroupDTO> rootResult = userGroupService.getRootGroupByOrgId(organizationDTO.getOrgId());
            userGroupDTO = rootResult.getData();
        } else {
            ServiceResult<OrganizationDTO> orgResult = organizationService.selectByOrgCode(orgCode);
            OrganizationDTO organizationDTO = orgResult.getData();
            if ("currentuser".equals(groupId)) {
                if (StringUtils.isBlank(organizationDTO.getRootGroupId())) {
                    return ServiceResult.success(new ArrayList<>());
                }
                // 当前用户所在的组织
                ServiceResult<List<UserWithGroupDTO>> userWithGroupResult = userUserGroupService.getUserWithGroup(userId);
                List<String> groupIds = userWithGroupResult.getData().stream().map(UserWithGroupDTO::getId).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(groupIds)) {
                    return ServiceResult.success(new ArrayList<>());
                }
                groupId = groupIds.get(0);
            }
            // 当前用户所在组织
            ServiceResult<UserGroupDTO> groupResult = userGroupService.getById(groupId);
            userGroupDTO = groupResult.getData();
            lastLevelId = userGroupDTO.getGroupLevelId();
            // 判断用户所在组织的父组织是否是根组织
            if (StringUtils.isNotBlank(userGroupDTO.getGroupParentId())) {
                ServiceResult<UserGroupDTO> rootResult = userGroupService.getRootGroupByOrgId(organizationDTO.getOrgId());
                userGroupDTO = rootResult.getData();
            }
        }
        // 根组织的levelId
        String levelId = userGroupDTO.getGroupLevelId();
        while (StringUtils.isNotBlank(levelId)) {
            ServiceResult<UserGroupLevelDTO> groupLevelRst = getById(levelId);
            UserGroupLevelDTO userGroupLevelDTO = groupLevelRst.getData();
            // 判断userGroupLevelDTO是否为空 兼容层级上传不更新末级层级的levelChildrenId
            if (Objects.nonNull(userGroupLevelDTO)) {
                groupLevelDTOList.add(userGroupLevelDTO);
            }
            if (levelId.equals(lastLevelId) || Objects.isNull(userGroupLevelDTO)) {
                break;
            }
            levelId = userGroupLevelDTO.getLevelChildrenId();
        }
        return ServiceResult.success(groupLevelDTOList);
    }

    @Override
    public ServiceResult<List<UserGroupLevelDTO>> listByOrgId(String orgId, UserGroupLevelDTO groupLevelDTO) {
        // 校验参数
        if (!ObjectId.isValid(orgId)) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_FORMAT, "org_id format error");
        }
        // 设置查询参数
        UserGroupLevelDO condition = groupLevelDTO != null ? userGroupLevelConvert.dtoToDo(groupLevelDTO) : new UserGroupLevelDO();
        condition.setOrgId(orgId);

        // 查询并设置返回值
        return ServiceResult.success(userGroupLevelConvert.dosToDtos(userGroupLevelDao.listByCondition(condition)));
    }

    @Override
    public ServiceResult<List<UserGroupLevelOldVO>> getLevels(TokenDTO currentToken, String levelId) {
        log.info("Now to getLevels");
        List<UserGroupLevelDTO> levelsAndDisplays;
        if (currentToken.isAdmin()) {
            levelsAndDisplays = getLevelsAndDisplay(currentToken, true).getData();
        } else {
            levelsAndDisplays = getLevelsAndDisplay(currentToken, false).getData();
            if (StringUtils.isNotEmpty(levelId)) {
                if (CollectionUtils.isNotEmpty(levelsAndDisplays)) {
                    levelsAndDisplays = levelsAndDisplays.stream()
                            .filter(l -> levelId.equals(l.getGroupLevelId())).collect(Collectors.toList());

                }
            }
        }
        return ServiceResult.success(UserGroupLevelConverter.levelDTOToOldVO(levelsAndDisplays));
    }

    @Override
    public ServiceResult putGroupLevel(TokenDTO token, String levelId, JSONObject obj) {
        UserGroupLevelDO update_level = userGroupLevelDao.getById(levelId);
        boolean can_save = false;
        if (UserEnum.USER_NO.getFlag().equals(token.getSuperRole()) && UserEnum.USER_NO.getFlag().equals(token.getIsSenior())) {
            List<String> group_ids = userGroupService.getUserGroupIds(token.getUserId(), null, true);
            for (String grp_id : group_ids) {
                UserGroupDO grp = userGroupDao.getById(grp_id);
                if (Objects.nonNull(grp)) {
                    String lv_id = grp.getGroupLevelId();
                    for (int i = 0; i < 100; i++) {
                        if (levelId.equals(lv_id)) {
                            can_save = true;
                            break;
                        }
                        UserGroupLevelDO level = userGroupLevelDao.getById(lv_id);
                        if (Objects.isNull(level)) {
                            throw new BusinessException(String.format("GroupLevel[id=%s] not found", lv_id));
                        }
                        if (level.getLevelNum() >= update_level.getLevelNum()) {
                            break;
                        }
                        lv_id = level.getLevelChildrenId();
                        if (StrUtil.isEmpty(lv_id)) {
                            break;
                        }
                    }
                }
            }
        } else {
            can_save = true;
        }
        if (can_save) {
            UserGroupLevelDO userGroupLevelDO = new UserGroupLevelDO();
            userGroupLevelDO.setLevelDisplay(obj.getJSONObject("display").toJSONString());
            userGroupLevelDao.updateById(levelId, userGroupLevelDO);
            return ServiceResult.success();
        } else {
            throw new BusinessException("no permission to save grouplevel");
        }
    }

}
